home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / modes / xrdb-mode.el.z / xrdb-mode.el
Encoding:
Text File  |  1998-05-21  |  13.6 KB  |  445 lines

  1. ;;; xrdb-mode.el --- mode for editing X resource database files
  2.  
  3. ;; Author:        1994-1997 Barry A. Warsaw
  4. ;; Maintainer:    tools-help@python.org
  5. ;; Created:       May 1994
  6. ;; Version:       1.21
  7. ;; Last Modified: 1997/02/24 03:34:56
  8. ;; Keywords:      data languages
  9.  
  10. ;; Copyright (C) 1994 Barry A. Warsaw
  11.  
  12. ;; This file is not part of GNU Emacs.
  13.  
  14. ;; This program is free software; you can redistribute it and/or modify
  15. ;; it under the terms of the GNU General Public License as published by
  16. ;; the Free Software Foundation; either version 2 of the License, or
  17. ;; (at your option) any later version.
  18. ;; 
  19. ;; This program is distributed in the hope that it will be useful,
  20. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. ;; GNU General Public License for more details.
  23. ;; 
  24. ;; You should have received a copy of the GNU General Public License
  25. ;; along with this program; if not, write to the Free Software
  26. ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  
  28. ;;; Commentary:
  29. ;;
  30. ;; In 1994 I wrote:
  31. ;;
  32. ;; "I used to be like you.  I used to hack on X resource database files
  33. ;;  all the time, and when I did, I found this mode to be fairly
  34. ;;  useful.  It's by no means perfect.  At one time I had a collection
  35. ;;  of hacks that did some nice indentation of resource lines, but
  36. ;;  they were not organized in any way.  This mode was my attempt to
  37. ;;  congeal this mess into a proper major mode.  I release it now, not
  38. ;;  because it will change your life, but because I don't plan to do
  39. ;;  anything more with it.
  40. ;;
  41. ;;  I have since been enlightened and no longer have to cavort with
  42. ;;  mere mortal X hackers anymore.  I like my brain cells, so now I
  43. ;;  use NEXTSTEP where all is glory.  Or would you say I traded one
  44. ;;  vice for another?  Hmm...  Anyway, if you are still down in the
  45. ;;  trenches and would like to inherit this file, let me know.  I
  46. ;;  don't intend to do any work on it any more... unless I lose my
  47. ;;  place in paradise.  I promise to be good, Steve.  :-) :-)"
  48. ;;
  49. ;; I have fallen from grace and have been kicked out of paradise.  So
  50. ;; has Steve Jobs apparently :-)
  51. ;;
  52. ;; To use, put the following in your .emacs:
  53. ;;
  54. ;; (autoload 'xrdb-mode "xrdb-mode" "Mode for editing X resource files" t)
  55. ;;
  56. ;; You may also want something like:
  57. ;;
  58. ;; (setq auto-mode-alist
  59. ;;       (append '(("\\.Xdefaults$" . xrdb-mode)
  60. ;;                 ("\\.Xenvironment$" . xrdb-mode)
  61. ;;                 ("\\.Xresources$" . xrdb-mode)
  62. ;;                 )
  63. ;;               auto-mode-alist))
  64.  
  65.  
  66. ;; Code:
  67.  
  68.  
  69. ;; These variables are available for your customization
  70. (defgroup xrdb nil
  71.   "Mode for editing X resource database files."
  72.   :group 'data
  73.   :group 'languages)
  74.  
  75. (defcustom xrdb-mode-hook nil
  76.   "*Hook to be run when `xrdb-mode' is entered."
  77.   :type 'hook
  78.   :group 'xrdb)
  79.  
  80. (defcustom xrdb-subdivide-by 'paragraph
  81.   "*Extent of alignment calculations.
  82. Can be one of `buffer', `paragraph', `page', or `line'.  Do a
  83. \\[describe-function] xrdb-indent-buffer RET for more information."
  84.   :type '(radio (const buffer) (const paragraph)
  85.         (const page) (const line))
  86.   :group 'xrdb)
  87.  
  88.  
  89.  
  90. ;; no need to customize anything below this line
  91. (defconst xrdb-comment-re "^[ \t]*[!]"
  92.   "Character which starts a comment.")
  93. (defconst xrdb-separator-char ?:
  94.   "Character which separates resource specs from values.")
  95.  
  96.  
  97. ;; utilities
  98. (defsubst xrdb-point (position)
  99.   ;; Returns the value of point at certain commonly referenced POSITIONs.
  100.   ;; POSITION can be one of the following symbols:
  101.   ;; 
  102.   ;; bol  -- beginning of line
  103.   ;; eol  -- end of line
  104.   ;; bod  -- beginning of defun
  105.   ;; boi  -- back to indentation
  106.   ;; ionl -- indentation of next line
  107.   ;; iopl -- indentation of previous line
  108.   ;; bonl -- beginning of next line
  109.   ;; bopl -- beginning of previous line
  110.   ;; bop  -- beginning of paragraph
  111.   ;; eop  -- end of paragraph
  112.   ;; bopg -- beginning of page
  113.   ;; eopg -- end of page
  114.   ;; 
  115.   ;; This function does not modify point or mark.
  116.   (let ((here (point)))
  117.     (cond
  118.      ((eq position 'bol)  (beginning-of-line))
  119.      ((eq position 'eol)  (end-of-line))
  120.      ((eq position 'boi)  (back-to-indentation))
  121.      ((eq position 'bonl) (forward-line 1))
  122.      ((eq position 'bopl) (forward-line -1))
  123.      ((eq position 'bop)  (forward-paragraph -1))
  124.      ((eq position 'eop)  (forward-paragraph 1))
  125.      ((eq position 'bopg)  (forward-page -1))
  126.      ((eq position 'eopg)  (forward-page 1))
  127.      (t
  128.       (error "unknown buffer position requested: %s" position)))
  129.     (prog1
  130.     (point)
  131.       (goto-char here))
  132.     ))
  133.  
  134. (defsubst xrdb-skip-to-separator ()
  135.   ;; skip forward from the beginning of the line to the separator
  136.   ;; character as given by xrdb-separator-char. Returns t if the
  137.   ;; char was found, otherwise, nil.
  138.   (beginning-of-line)
  139.   (skip-chars-forward
  140.    (concat "^" (char-to-string xrdb-separator-char))
  141.    (xrdb-point 'eol))
  142.   (= (following-char) xrdb-separator-char))
  143.  
  144.  
  145.  
  146. ;; commands
  147. (defun xrdb-electric-separator (arg)
  148.   "Insert the separator character.
  149. Re-align the line unless an argument is given."
  150.   (interactive "P")
  151.   ;; first insert the character
  152.   (self-insert-command (prefix-numeric-value arg))
  153.   ;; only do electric behavior if arg is not given
  154.   (if (not arg)
  155.       (xrdb-align-to (xrdb-point 'bol)
  156.              (xrdb-point 'bonl)
  157.              (save-excursion
  158.                (beginning-of-line)
  159.                (forward-comment (- (point-max)))
  160.                (beginning-of-line)
  161.                (xrdb-skip-to-separator)
  162.                (current-column)))))
  163.  
  164. (defun xrdb-align-to (start end goalcolumn)
  165.   (interactive "r\nnAlign to column: ")
  166.   (save-excursion
  167.     (save-restriction
  168.       (narrow-to-region start end)
  169.       (beginning-of-buffer)
  170.       (while (< (point) (point-max))
  171.     (if (and (not (looking-at xrdb-comment-re))
  172.          (xrdb-skip-to-separator)
  173.          goalcolumn)
  174.         (indent-code-rigidly (xrdb-point 'bol)
  175.                  (xrdb-point 'bonl)
  176.                  (- goalcolumn (current-column))))
  177.     (forward-line 1)))))
  178.  
  179. (defun xrdb-indent-line (arg)
  180.   "Re-align current line."
  181.   (interactive "P")
  182.   ;; narrow to the region specified by xrdb-subdivide-by
  183.   (save-excursion
  184.     (save-restriction
  185.       (widen)
  186.       (cond
  187.        ((eq xrdb-subdivide-by 'buffer))
  188.        ((eq xrdb-subdivide-by 'page)
  189.     (narrow-to-page))
  190.        ((eq xrdb-subdivide-by 'paragraph)
  191.     (narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop)))
  192.        (t
  193.     (narrow-to-region (xrdb-point 'bopl) (xrdb-point 'bonl))
  194.     ))
  195.       ;; indent line
  196.       (xrdb-align-to (xrdb-point 'bol) (xrdb-point 'bonl)
  197.              (xrdb-region-goal-column))
  198.       )))
  199.  
  200. (defun xrdb-indent-region (start end)
  201.   "Re-align region."
  202.   (interactive "r")
  203.   ;; narrow to region
  204.   (save-excursion
  205.     (save-restriction
  206.       (narrow-to-region start end)
  207.       (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
  208.       )))
  209.  
  210. (defun xrdb-indent-page ()
  211.   "Re-align the current page."
  212.   (interactive)
  213.   (save-excursion
  214.     (save-restriction
  215.       (narrow-to-page)
  216.       (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
  217.       )))
  218.  
  219. (defun xrdb-indent-paragraph ()
  220.   "Re-align the current paragraph."
  221.   (interactive)
  222.   (save-excursion
  223.     (save-restriction
  224.       (narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop))
  225.       (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
  226.       )))
  227.  
  228. (defun xrdb-indent-buffer (arg)
  229.   "Re-align the entire buffer.
  230. Alignment calculations are controlled by the variable
  231. `xrdb-subdivide-by', which can take the values `buffer', `paragraph',
  232. `page', or `line', with the following meanings:
  233.  
  234.  buffer - all non-comment lines are aligned with the longest line in
  235.           the buffer.  Since every line must be scanned, this will
  236.       take the longest to perform.
  237.  
  238.  paragraph - alignment of lines spanning paragraphs. A paragraph is
  239.              defined as all contiguous lines between blank or comment
  240.          lines.
  241.  
  242.  page - alignment of lines spanning pages (i.e. separated by
  243.         page-delimiter, usually ^L).
  244.  
  245.  none - alignment of lines based on the previous line.
  246.  
  247. With optional \\[universal-argument], queries for alignment subdivision."
  248.   (interactive "P")
  249.   (let ((align-by (if (not arg)
  250.               xrdb-subdivide-by
  251.             (completing-read
  252.              "Align by: "
  253.              '(("buffer" . buffer)
  254.                ("paragraph" . paragraph)
  255.                ("page" . page)
  256.                ("line" . line))
  257.              nil t (format "%s" xrdb-subdivide-by)))))
  258.     (message "Aligning by %s..." align-by)
  259.     (save-excursion
  260.       (save-restriction
  261.     (widen)
  262.     (cond
  263.      ;; by buffer
  264.      ((eq align-by 'buffer)
  265.       (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)))
  266.      ;; by paragraph
  267.      ((eq align-by 'paragraph)
  268.       (beginning-of-buffer)
  269.       (while (< (point) (point-max))
  270.         (narrow-to-region (point) (xrdb-point 'eop))
  271.         (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
  272.         (beginning-of-buffer)
  273.         (widen)
  274.         (forward-paragraph 1)
  275.         ))
  276.      ;; by page
  277.      ((eq align-by 'page)
  278.       (beginning-of-buffer)
  279.       (while (< (point) (point-max))
  280.         (narrow-to-region (point) (xrdb-point 'eopg))
  281.         (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
  282.         (beginning-of-buffer)
  283.         (widen)
  284.         (forward-page 1)
  285.         ))
  286.      ;; by line
  287.      (t
  288.       (beginning-of-buffer)
  289.       (let ((prev-goalcol 0))
  290.         (while (< (point) (point-max))
  291.           ;; skip comments and blank lines
  292.           (if (not (looking-at paragraph-start))
  293.           (progn
  294.             (xrdb-align-to (xrdb-point 'bol) (xrdb-point 'bonl)
  295.                    prev-goalcol)
  296.             (xrdb-skip-to-separator)
  297.             (setq prev-goalcol (- (point) (xrdb-point 'boi)))
  298.             ))
  299.           (forward-line 1))))
  300.      )))
  301.     (message "Aligning by %s... done." align-by)
  302.     ))
  303.  
  304.  
  305. ;; major-mode stuff
  306. (defvar xrdb-mode-abbrev-table nil
  307.   "Abbrev table used in `xrdb-mode' buffers.")
  308. (define-abbrev-table 'xrdb-mode-abbrev-table ())
  309.  
  310.  
  311. (defvar xrdb-mode-syntax-table nil
  312.   "Syntax table used in `xrdb-mode' buffers.")
  313. (if xrdb-mode-syntax-table
  314.     ()
  315.   (setq xrdb-mode-syntax-table (make-syntax-table))
  316.   (modify-syntax-entry ?!  "<" xrdb-mode-syntax-table)
  317.   (modify-syntax-entry ?\n ">" xrdb-mode-syntax-table))
  318.  
  319.  
  320. (defvar xrdb-mode-map ()
  321.   "Keymap used in `xrdb-mode' buffers.")
  322. (if xrdb-mode-map
  323.     ()
  324.   (setq xrdb-mode-map (make-sparse-keymap))
  325.   (let ((ekey (char-to-string xrdb-separator-char)))
  326.     ;; make the separator key electric
  327.     (define-key xrdb-mode-map ekey 'xrdb-electric-separator)
  328.     (define-key xrdb-mode-map "\t" 'xrdb-indent-line)
  329.     (define-key xrdb-mode-map "\C-c\C-a" 'xrdb-indent-paragraph)
  330.     (define-key xrdb-mode-map "\C-c\C-b" 'xrdb-submit-bug-report)
  331.     (define-key xrdb-mode-map "\C-c\C-p" 'xrdb-indent-page)
  332.     (define-key xrdb-mode-map "\C-c\C-r" 'xrdb-indent-region)
  333.     (define-key xrdb-mode-map "\C-c\C-u" 'xrdb-indent-buffer)
  334.     (define-key xrdb-mode-map "\C-c>"    'xrdb-align-to)
  335.     ))
  336.  
  337. ;;;###autoload
  338. (defun xrdb-mode ()
  339.   "Major mode for editing xrdb config files"
  340.   (interactive)
  341.   (kill-all-local-variables)
  342.   (set-syntax-table xrdb-mode-syntax-table)
  343.   (setq major-mode 'xrdb-mode
  344.     mode-name "xrdb"
  345.     local-abbrev-table xrdb-mode-abbrev-table)
  346.   (use-local-map xrdb-mode-map)
  347.   ;; local variables
  348.   (make-local-variable 'parse-sexp-ignore-comments)
  349.   (make-local-variable 'comment-start)
  350.   (make-local-variable 'comment-end)
  351.   (make-local-variable 'paragraph-start)
  352.   (make-local-variable 'paragraph-separate)
  353.   (make-local-variable 'paragraph-ignore-fill-prefix)
  354.   ;; now set their values
  355.   (setq parse-sexp-ignore-comments t
  356.     comment-start "! "
  357.     comment-end "")
  358.   (setq indent-region-function 'xrdb-indent-region
  359.     paragraph-ignore-fill-prefix t
  360.     paragraph-start (concat "^[ \t]*$\\|^[ \t]*[!]\\|" page-delimiter)
  361.     paragraph-separate paragraph-start)
  362.   (run-hooks 'xrdb-mode-hook))
  363.  
  364.  
  365.  
  366. ;; faces and font-locking
  367. (defvar xrdb-option-name-face 'xrdb-option-name-face
  368.   "Face for option name on a line in an X resource db file")
  369. (defvar xrdb-option-value-face 'xrdb-option-value-face
  370.   "Face for option value on a line in an X resource db file")
  371.  
  372. (make-face 'xrdb-option-name-face)
  373. (make-face 'xrdb-option-value-face)
  374.  
  375. (defun xrdb-font-lock-mode-hook ()
  376.   (or (face-differs-from-default-p 'xrdb-option-name-face)
  377.       (copy-face 'font-lock-keyword-face 'xrdb-option-name-face))
  378.   (or (face-differs-from-default-p 'xrdb-option-value-face)
  379.       (copy-face 'font-lock-string-face 'xrdb-option-value-face))
  380.   (remove-hook 'font-lock-mode-hook 'xrdb-font-lock-mode-hook))
  381. (add-hook 'font-lock-mode-hook 'xrdb-font-lock-mode-hook)
  382.  
  383. (defvar xrdb-font-lock-keywords
  384.   (list '("^[ \t]*\\([^\n:]*:\\)[ \t]*\\(.*\\)$"
  385.       (1 xrdb-option-name-face)
  386.       (2 xrdb-option-value-face)))
  387.   "Additional expressions to highlight in X resource db mode.")
  388. (put 'xrdb-mode 'font-lock-defaults '(xrdb-font-lock-keywords))
  389.  
  390.  
  391.  
  392. ;; commands
  393. (defun xrdb-region-goal-column ()
  394.   ;; Returns the goal column of the current region.  Assumes the
  395.   ;; buffer has been narrowed to the region to scan.
  396.   (save-excursion
  397.     (beginning-of-buffer)
  398.     (let ((goalcol -1)
  399.       linecol)
  400.       (while (< (point) (point-max))
  401.     ;; skip any comments
  402.     (if (and (not (looking-at xrdb-comment-re))
  403.          (xrdb-skip-to-separator)
  404.          (< goalcol (setq linecol (current-column)))
  405.          )
  406.         (setq goalcol linecol))
  407.     (forward-line 1))
  408.       (if (< goalcol 0)
  409.       nil
  410.     goalcol))))
  411.  
  412.  
  413.  
  414. ;; submitting bug reports
  415.  
  416. (defconst xrdb-version "1.21"
  417.   "xrdb-mode version number.")
  418.  
  419. (defconst xrdb-mode-help-address "tools-help@python.org"
  420.   "Address for xrdb-mode bug reports.")
  421.  
  422. (eval-when-compile
  423.   (require 'reporter))
  424.  
  425. (defun xrdb-submit-bug-report ()
  426.   "Submit via mail a bug report on xrdb-mode."
  427.   (interactive)
  428.   ;; load in reporter
  429.   (let ((reporter-prompt-for-summary-p t)
  430.     (varlist '(xrdb-subdivide-by
  431.            xrdb-mode-hook
  432.            )))
  433.     (and (if (y-or-n-p "Do you want to submit a report on xrdb-mode? ")
  434.          t
  435.        (message "")
  436.        nil)
  437.      (require 'reporter)
  438.      (reporter-submit-bug-report
  439.       xrdb-mode-help-address "xrdb-mode" varlist nil nil "Dear Barry,")
  440.      )))
  441.  
  442.  
  443. (provide 'xrdb-mode)
  444. ;; xrdb-mode.el ends here
  445.